package com.gopay.common.base.dao.impl;

import java.io.Serializable;
import java.sql.SQLException;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.HibernateTemplate;

import com.gopay.common.base.dao.BaseDAO;

/**
 * 
 * @BaseDAO.java
 * @author
 * @2012-12-21 下午2:15:10 www.gopay.com.cn Inc.All rights reserved.
 */
@SuppressWarnings("all")
public class BaseDAOImpl<T extends Serializable, Pk extends Serializable> extends BaseReadDAOImpl<T, Pk> implements BaseDAO<T, Pk> {

    @Resource(name = "hibernateTemplate")
    protected HibernateTemplate hibernateTemplate;

    public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
        this.hibernateTemplate = hibernateTemplate;
    }

    public HibernateTemplate getHibernateTemplate() {
        return hibernateTemplate;
    }
    
    public T save(T entity) {
        getHibernateTemplate().save(entity);
        return entity;
    }
    
    public void saveOrUpdateAll(Collection<T> entityList){
    	getHibernateTemplate().saveOrUpdateAll(entityList);
    }
    
    public void delete(T entity) {
        getHibernateTemplate().delete(entity);
    }

    public void deleteAll(Collection<T> collection) {
        getHibernateTemplate().deleteAll(collection);
    }


    public void update(T entity) {
        getHibernateTemplate().update(entity);
    }


    public int deleteByHql(final String hql) {
        return (Integer) getHibernateTemplate().execute(new HibernateCallback() {
            public Object doInHibernate(Session session) throws HibernateException, SQLException {
                Query query = session.createQuery(hql);
                return query.executeUpdate();
            }
        });
    }

    public int updateByHql(final String hql) {
        return (Integer) getHibernateTemplate().execute(new HibernateCallback() {
            public Object doInHibernate(Session session) throws HibernateException, SQLException {
                Query query = session.createQuery(hql);
                return query.executeUpdate();
            }
        });
    }

    public int updateByHql(final String hql, final Map<String, Object> param) {
        return (Integer) getHibernateTemplate().execute(new HibernateCallback() {
            public Object doInHibernate(Session session) throws HibernateException, SQLException {
                Query query = session.createQuery(hql);
                if (param != null && param.size() != 0) {
                    Iterator<String> it = param.keySet().iterator();
                    while (it.hasNext()) {
                        String key = it.next();
                        Object value = param.get(key);
                        if(value instanceof List) {
                        	query.setParameterList(key, (List) value);
                        } else if (value instanceof Object[]) {
                            query.setParameterList(key, (Object[]) value);
                        } else {
//                            query.setString(key, param.get(key).toString());
                            query.setParameter(key, param.get(key));
                        }
                    }
                }
                return query.executeUpdate();
            }
        });
    }

    public int updateBySql(final String sql, final Map<String, Object> param) {
        return (Integer) getHibernateTemplate().execute(new HibernateCallback() {
            public Object doInHibernate(Session session) throws HibernateException, SQLException {
                Query query = session.createSQLQuery(sql);
                if (param != null && param.size() != 0) {
                    Iterator<String> it = param.keySet().iterator();
                    while (it.hasNext()) {
                        String key = it.next();
                        Object value = param.get(key);
                        if (value instanceof Object[]) {
                            query.setParameterList(key, (Object[]) value);
                        } else {
//                            query.setString(key, param.get(key).toString());
                            query.setParameter(key, param.get(key));
                        }
                    }
                }
                return query.executeUpdate();
            }
        });
    }
    
    public int bulkUpdate(String queryString) {
        return getHibernateTemplate().bulkUpdate(queryString);
    }

    public int bulkUpdate(String queryString, Object[] values) {
        return getHibernateTemplate().bulkUpdate(queryString, values);
    }

    @Override
    public T merge(T entity) {
        return getHibernateTemplate().merge(entity);
    }
    
    
}
